// 导入需要使用的类型和库
import type { Plugin } from 'vite'
import type { AddressInfo } from 'net'
import { spawn } from 'child_process'
import fs from 'fs'

// 导出Vite插件函数
export const viteElectronDev = (): Plugin => {
  return {
    name: 'vite-electron-dev',
    // 在configureServer中实现插件的逻辑
    /**
     * configureServer是Vite的一个插件钩子函数，用于在Vite开发服务器启动时执行一些自定义逻辑。
     * 该函数接受一个ServerOptions对象作为参数，该对象包含有关当前Vite服务器的配置信息。
     * 在这个钩子函数中，您可以访问Vite服务器的HTTP服务器对象（httpServer），WebSocket服务器对象（wsServer）和Vite的构建配置对象（config）等。
     * 您可以使用这些对象来实现各种功能，例如自定义路由、添加中间件、实现实时重载和调试等。
     */
    configureServer(server) {
      // 定义初始化Electron的函数
      const initElectron = () => {
        // 使用esbuild编译TypeScript代码为JavaScript
        require('esbuild').buildSync({
          entryPoints: ['src/background.ts'], // 指定要编译的入口文件，这里是src/background.ts。
          bundle: true, // 指定是否打包所有依赖项，这里是true，表示需要打包所有依赖项。
          outfile: 'dist/background.js', // 指定输出文件的路径和名称，这里是dist/background.js。
          platform: 'node', // 指定编译的目标平台，这里是node，表示编译为Node.js可用的代码。
          target: 'node12', // 指定编译的目标JavaScript版本，这里是node12，表示编译为Node.js 12及以上版本可用的代码。
          external: ['electron'] // 指定不需要被打包的外部依赖项，这里是['electron']，表示electron模块不需要被打包。
        })
        // 在这段代码中，esbuild会将src/background.ts文件编译为JavaScript 并且放入dist
      }

      // 调用初始化Electron函数
      initElectron()

      // 监听Vite的HTTP服务器的listening事件
      server?.httpServer?.once('listening', () => {
        // 获取HTTP服务器的监听地址和端口号
        const addressInfo = server?.httpServer?.address() as AddressInfo
        const IP = `http://localhost:${addressInfo.port}`
        // 启动Electron进程
        let electronProcess = spawn('electron', ['dist/background.js', IP])

        // 监听主进程代码的更改
        // fs.watch 主要实现热更新
        // 每次background.ts 修改完成就会重新启动electron进程
        fs.watchFile('src/background.ts', () => {
          // 杀死当前的Electron进程
          electronProcess.kill()
          // 重新编译主进程代码并重新启动Electron进程
          initElectron()
          electronProcess = spawn('electron', ['dist/background.js', IP])
        })

        // 监听Electron进程的stdout输出
        electronProcess.stdout?.on('data', (data) => {
          console.log(`日志: ${data}`)
        })
      })
    }
  }
}
